module.exports = (app) => {
    const User = require('../../models/User');
    const PM = require('../../models/PrivateMessage');
    const GM = require('../../models/GroupMessage');

    const Blog = require('../../models/Blog');
    const Comment = require('../../models/Comment');

    const jwt = require('jsonwebtoken');

    app.get('/update', async function (req, res) {
        let list = await PM.find();
        for (let item of list) {
            item.listLength = item.mList.length;
            item.save();
        }
        res.send(list);
    })

    app.get('/api/main/getUserData', authMiddleware, async function(req, res) {
        let user = await User
            .findById(req.user._id)
            .populate('friends')
            .populate('friendReq')
            .populate('currentMessage.opposite')
            .populate('currentMessage.message');
        res.send(user);
    })

    app.get('/api/main/searchUser/:username', authMiddleware, async function(req, res) {
        let user = await User.findOne({username: req.params.username});
        if (!user) {
            return res.send({
                user: null,
                message: '找不到此用户'
            })
        }
        res.send({
            user: user,
            message: '搜索成功'
        });
    })

    app.get('/api/chat/getOpposite/:id', authMiddleware, async function(req, res) {
        let user = await User.findById(req.params.id);
        res.send(user);
    })

    app.post('/api/main/setSignature', authMiddleware, function (req, res) {
        const {text} = req.body;
        req.user.signature = text;
        req.user.save();
        res.send({
            message: 'success',
        })
    })

    app.get('/api/blog/getBlog/:uid', async function (req, res) {
        const user = await User.findById(req.params.uid).populate('blogs');

        let id = '';
        let token = String(req.headers.authorization || '').split(' ').pop();
        if (token) {
            id = jwt.verify(token, app.get('secret')).id;
        }

        res.send({
            user: user,
            self: id === req.params.uid
        });
    })

    app.get('/api/blog/article/:id', async function (req, res) {
        const article =
            await Blog.findById(req.params.id)
                .populate('poster')
                .populate('comment');
        res.send(article);
    })

    app.post('/api/blog/likePost/', async function (req, res) {
        const {id, status} = req.body;
        const article = await Blog.findById(id);
        article.like += status ? -1 : 1;
        article.save();
        res.send();
    })

    app.post('/api/blog/likeComment', async function (req, res) {
        const {id, status} = req.body;
        const comment = await Comment.findById(id);
        comment.like += status ? -1 : 1;
        comment.save();
        res.send();
    })

    app.post('/api/blog/postComment/', async function (req, res) {
        const {aid, post} = req.body;
        const blog = await Blog.findById(aid);
        let comment = await Comment.create({
            poster: post.name,
            content: post.content,
        })
        blog.comment.push(comment);
        blog.save();
        res.send({message: 'success'});
    })

    app.post('/api/blog/post', authMiddleware, async function (req, res) {
        const {title, abstract, post} = req.body;
        let blog = await Blog.create({
            poster: req.user._id,
            title: title,
            abstract: abstract,
            content: post,
        })
        req.user.blogs.unshift(blog);
        req.user.save();
        res.send(blog);
    })

    app.post('/api/blog/deleteBlog', authMiddleware, async function (req, res) {
        let {id} = req.body;
        let blogs = req.user.blogs;
        for (let i = 0; i < blogs.length; i++) {
            if (blogs[i].toString() === id) {
                const blog = await Blog.findById(id);
                for (let item of blog.comment) {
                    await Comment.findByIdAndDelete(item);
                }
                blog.delete();
                blogs.splice(i, 1);
                break
            }
        }
        req.user.save();

        res.send();
    })

    const multer = require('multer');
    const imgStorage = multer.diskStorage({
        destination: function (req, file, cb) {
            cb(null, __dirname + '/../../uploads/imgs')
        },
        filename: function (req, file, cb) {
            cb(null, file.fieldname + Date.now() + '.' + file.mimetype.split('/')[1])
        }
    })
    const uploadImg = multer({storage: imgStorage});
    app.post(
        '/api/chat/postImg',
        authMiddleware,
        uploadImg.single('img'),
        function (req, res) {
            let url = `uploads/imgs/${req.file.filename}`;
            res.send(url);
        }
    )
    app.post(
        '/api/blog/postImg',
        uploadImg.single('img'),
        function (req, res) {
            let url = `uploads/imgs/${req.file.filename}`;
            res.send({
                error: 0,
                data: {
                    url: url,
                    filename: req.file.filename,
                }
            });
        }
    )

    const avatarStorage = multer.diskStorage({
        destination: function (req, file, cb) {
            cb(null, __dirname + '/../../uploads/avatars')
        },
        filename: function (req, file, cb) {
            cb(null, file.fieldname + Date.now() + '.jpg')
        }
    })
    const uploadAvatar = multer({storage: avatarStorage});
    app.post('/api/main/avatarImgUpload',
        authMiddleware,
        uploadAvatar.single('avatar'),
        function (req, res) {
            res.send({
                url: `uploads/avatars/${req.file.filename}`,
                filename: req.file.filename,
            });
        }
    )

    const fileStorage = multer.diskStorage({
        destination: function (req, file, cb) {
            cb(null, __dirname + '/../../uploads/files')
        },
        filename: function (req, file, cb) {
            let name = file.originalname.split('.');
            cb(null, name[0] + Date.now() + '.' + name[1]);
        }
    })
    const uploadFile = multer({storage: fileStorage});
    app.post('/api/chat/fileUpload',
        authMiddleware,
        uploadFile.single('file'),
        function (req, res) {
            res.send({
                url: `uploads/files/${req.file.filename}`,
                filename: req.file.filename,
            });
        }
    )

    app.post('/api/main/avatarChange', authMiddleware, function (req, res) {
        let {url, scale, pos} = req.body;
        req.user.profile = {
            url: url,
            scale: scale,
            pos: pos
        };
        req.user.save();
        res.send({
            message: 'success'
        })
    })

    app.post('/api/register', async function (req, res) {
        const {username} = req.body;
        if (await User.findOne({username})) {
            return res.status(422).send({
                message: '用户名已存在'
            });
        }
        await User.create(req.body);
        res.send({
            success: true,
        })
    })

    app.post('/api/login', async function (req, res) {
        const {username, password} = req.body;
        const user = await User.findOne({username}).select('+password');
        assert(res, user, 422, '用户名不存在');
        let isValid = require('bcrypt').compareSync(password, user.password);
        assert(res, isValid, 422, '密码错误');
        let token = jwt.sign({id : user._id}, app.get('secret'));
        res.send({token});
    })

    async function authMiddleware(req, res, next) {
        let token = String(req.headers.authorization || '').split(' ').pop();
        assert(res, token, 401, '请提供token');
        let {id} = jwt.verify(token, app.get('secret'));
        assert(res, id, 401, '无效的token')
        req.user = await User.findById(id);
        assert(res, req.user, 401, '用户不存在')
        await next();
    }
    
    function assert(res, item, code, message) {
        if (!item) {
            return res.status(code).send({message});
        }
    }
}